/*
* Smart IP Camera
* Copyright (c) BZ <bzchen@allwinnertech.com>
*
* This file is part of SIPC.
*/
#ifndef Z_LIST_H
#define Z_LIST_H
#include <ZTypes.h>

#define Z_LIST_POISON1  ((void *) 0x00700700) 
#define Z_LIST_POISON2  ((void *) 0x00900900) 

typedef struct ZListNodeS ZListNodeT;
typedef struct ZListS ZListT;

struct ZListNodeS
{
    struct ZListNodeS *next;
    struct ZListNodeS *prev;
};

struct ZListS
{
    struct ZListNodeS *head;
    struct ZListNodeS *tail;
};

#define ZListInit(list) do { \
    (list)->head = (list)->tail = (struct ZListNodeS *)(list);\
    }while (0)
    
#define ZListNodeInit(node) do { \
    (node)->next = (node)->prev = (node);\
    }while (0)

#ifdef __cplusplus
extern "C"
{
#endif


static inline void __ZListAdd(struct ZListNodeS *new,
                        struct ZListNodeS *prev, struct ZListNodeS *next)
{
	next->prev = new;
	new->next = next;
	new->prev = prev;
	prev->next = new;
}

static inline void ZListAdd(struct ZListNodeS *new, struct ZListS *list)
{
	__ZListAdd(new, (struct ZListNodeS *)list, list->head);
}

static inline void ZListAddBefore(struct ZListNodeS *new, 
                                    struct ZListNodeS *pos)
{
	__ZListAdd(new, pos->prev, pos);
}

static inline void ZListAddAfter(struct ZListNodeS *new, 
                                    struct ZListNodeS *pos)
{
	__ZListAdd(new, pos, pos->next);
}

static inline void ZListAddTail(struct ZListNodeS *new, struct ZListS *list)
{
	__ZListAdd(new, list->tail, (struct ZListNodeS *)list);
}

static inline void __ZListDel(struct ZListNodeS *prev, struct ZListNodeS *next)
{
	next->prev = prev;
	prev->next = next;
}

static inline void ZListDel(struct ZListNodeS *node)
{
	__ZListDel(node->prev, node->next);
	node->next = Z_LIST_POISON1;
	node->prev = Z_LIST_POISON2;
}

static inline int ZListEmpty(const struct ZListS *list)
{
	return (list->head == (struct ZListNodeS *)list) 
	       && (list->tail == (struct ZListNodeS *)list);
}

#ifdef __cplusplus
}
#endif

#define ZListEntry(ptr, type, member) \
	ZContainerOf(ptr, type, member)

#define ZListFirstEntry(ptr, type, member) \
	ZListEntry((ptr)->head, type, member)

#define ZListForEach(pos, list) \
	for (pos = (list)->head; \
	        pos != (struct ZListNodeS *)(list);\
	        pos = pos->next)

#define ZListForEachPrev(pos, list) \
	for (pos = (list)->tail; \
	    pos != (struct ZListNodeS *)(list); \
	    pos = pos->prev)

#define ZListForEachSafe(pos, n, list) \
	for (pos = (list)->head, n = pos->next; \
	    pos != (struct ZListNodeS *)(list); \
		pos = n, n = pos->next)

#define ZListForEachPrevSafe(pos, n, list) \
	for (pos = (list)->tail, n = pos->prev; \
	     pos != (struct ZListNodeS *)(list); \
	     pos = n, n = pos->prev)

#define ZListForEachEntry(pos, list, member)				\
	for (pos = ZListEntry((list)->head, typeof(*pos), member);	\
	     &pos->member != (struct ZListNodeS *)(list); 	\
	     pos = ZListEntry(pos->member.next, typeof(*pos), member))

#define ZListForEachEntryReverse(pos, list, member)			\
	for (pos = ZListEntry((list)->tail, typeof(*pos), member);	\
	     &pos->member != (struct ZListNodeS *)(list); 	\
	     pos = ZListEntry(pos->member.prev, typeof(*pos), member))

#define ZListForEachEntrySafe(pos, n, list, member)			\
	for (pos = ZListEntry((list)->head, typeof(*pos), member),	\
		n = ZListEntry(pos->member.next, typeof(*pos), member);	\
	     &pos->member != (struct ZListNodeS *)(list); 					\
	     pos = n, n = ZListEntry(n->member.next, typeof(*n), member))

#define ZListForEachEntrySafeReverse(pos, n, list, member)		\
	for (pos = ZListEntry((list)->prev, typeof(*pos), member),	\
		n = ZListEntry(pos->member.prev, typeof(*pos), member);	\
	     &pos->member != (struct ZListNodeS *)(list); 					\
	     pos = n, n = ZListEntry(n->member.prev, typeof(*n), member))

#endif
